﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using T4Template.Bl;
using T4Template.Dto;
using T4Template.Model;
using T4Template.ProjectBL;

namespace T4Template.Controller
{
    class CodeGenerateController
    {
         private CodeGenerateBL CodeGenerateBL;

        public CodeGenerateController()
        {
            CodeGenerateBL = new CodeGenerateBL();
        }

        public CreateTemplateResultModel GenerateCode(GenerateCodeModel model)
        {
            CreateTemplateResultModel resultModel = new CreateTemplateResultModel();

            GenerateCodeDto dto = new GenerateCodeDto();
            foreach (var item in model.ClassModel)
            {
                ClassModelDto classDto = new ClassModelDto();
                classDto.Id = item.Id;
                classDto.Name = item.Name;

                foreach (var attribute in item.GetAttributes())
                {
                    AttributeModelDto attributeDto = new AttributeModelDto();
                    attributeDto.Id = attribute.Id;
                    attributeDto.ClassModel = classDto;
                    attributeDto.Name = attribute.Name;
                    attributeDto.Display = attribute.Display;
                    attributeDto.Search = attribute.Search;
                    attributeDto.SearchResult = attribute.SearchResult;
                    attributeDto.DataType = attribute.DataType;
                    attributeDto.FieldDescription = attribute.FieldDescription;
                    attributeDto.Label = attribute.Label;
                    attributeDto.FieldType = attribute.FieldType;
                    attributeDto.Length = attribute.Length;
                    attributeDto.Autokey = attribute.Autokey;
                    attributeDto.Nullable = attribute.Nullable;
                    attributeDto.Pk = attribute.Pk;
                    attributeDto.SeqNo = attribute.SeqNo;
                    attributeDto.DisplayLengthInGrid = attribute.DisplayLengthInGrid;
                    classDto.AddAttribute(attributeDto);
                }

                dto.ClassModel.Add(classDto);

            }


            dto.PatternType = model.PatternType;
            dto.CodeType = model.CodeType;
            dto.ToDirectory = model.PrimaryOutputDirectory;
            dto.SolutionName = model.SolutionName;
            dto.MvcProjectName = model.MvcProjectName;
            dto.BlProjectName = model.BlProjectName;
            dto.DalProjectName = model.DalProjectName;
            dto.StartupProjectDirectory = model.TemplateDirectory;
            dto.CompleteProjectDirectory = model.CompleteProjectDirectory;
            dto.FolderTemplate = model.FolderTemplate;
            dto.project = new Dto.ProjectDto
            {
                Name = model.project.Name
            };

            ActionResultDto<CodeTemplateDto> resultDto = CodeGenerateBL.Generate(dto);
            resultModel.Status = resultDto.Status;
            resultModel.ErrorMessage = resultDto.ErrorMessage;

            return resultModel;
        }

        public Dto.UserDto Login(LoginDto login)
        {
            ProjectBLClient obj = new ProjectBLClient();
            var result = obj.Login(login);
            Dto.UserDto objResult = null;
            if (result.Status)
            {
                objResult = new Dto.UserDto
                {
                    CreateDate = result.Data.CreateDate,
                    Id = result.Data.Id,
                    LastLogin = result.Data.LastLogin,
                    Password = result.Data.Password,
                    UserName = result.Data.UserName
                };
            }
            else
            {
                throw new Exception(result.ErrorMessage);
            }
            return objResult;
        }

        public int AddUser(Dto.UserDto user)
        {
            ProjectBLClient obj = new ProjectBLClient();
            var result = obj.AddUser(new ProjectBL.AddUserDto
             {
                 Password = user.Password,
                 UserName = user.UserName
             });
            int userId = 0;
            if (result.Status)
                userId = result.Data;
            else
            {
                throw new Exception(result.ErrorMessage);
            }
            return userId;
        }

        public int AddProject(Dto.ProjectDto project)
        {
            ProjectBLClient obj = new ProjectBLClient();
            var result = obj.AddProject(new ProjectBL.ProjectDto
            {
                CreateTime = project.CreateDate,
                Id = project.Id,
                LastUpdate = project.LastUpdate,
                Name = project.Name,
                Platform = project.Platform,
                StyleId = project.StyleId,
                UserId = project.UserId,
                Version = project.Version
            });
            int projectId = 0;
            if (result.Status)
                projectId = result.Data;
            else
            {
                throw new Exception(result.ErrorMessage);
            }
            return projectId;
        }

        public ProjectBL.ProjectDto GetProject(int projectId)
        {
            ProjectBLClient obj = new ProjectBLClient();
            var objTemp = obj.GetProject(new ProjectPKDto
            {
                 ProjectId = projectId
            });
            ProjectBL.ProjectDto objResult = null;
            if (objTemp.Status)
            {
                objResult = objTemp.Data;
            }
            else
            {
                throw new Exception(objTemp.ErrorMessage);
            }
            return objResult; 
        }

        public List<ProjectBL.ProjectHeaderDto> GetProjectNameByUserId(int userId)
        {
            List<ProjectBL.ProjectHeaderDto> objResult = null;

            ProjectBLClient obj = new ProjectBLClient();
            var objTemp = obj.GetProjectNameByUserId(new UserPkDto
            {
                 UserId = userId
            });
            if (objTemp.Status)
            {
                objResult = objTemp.Data;
            }
            else
            {
                throw new Exception(objTemp.ErrorMessage);
            }
            return objResult;
        }

        public ClassModelDto GetClass(int classId)
        {
            CodeGenBL.CodeGenBLClient objCodeGen = new CodeGenBL.CodeGenBLClient();
            ClassModelDto obj = null;
            var objTemp = objCodeGen.GetClass(new CodeGenBL.ClassPkDto
            {
                ClassId = classId
            });
            if (objTemp.Status)
            {
                obj = new ClassModelDto
                {
                    Id = objTemp.Data.Id,
                    Name = objTemp.Data.Name,
                    ProjectId = objTemp.Data.ProjectId

                };
                if (objTemp.Data.Attributes != null)
                {
                    foreach (var item in objTemp.Data.Attributes)
                    {
                        obj.AddAttribute(new AttributeModelDto
                        {
                            Autokey = item.AutoKey,
                            DataType = item.DataType,
                            Display = item.Display,
                            DisplayLengthInGrid = item.DisplayLengthInGrid,
                            FieldDescription = item.FieldDescription,
                            FieldType = item.FieldType,
                            Id = item.Id,
                            Label = item.Label,
                            Length = item.Length,
                            Name = item.Name,
                            Nullable = item.Nullable,
                            Pk = item.Pk,
                            Search = item.Search,
                            SearchResult = item.SearchResult,
                            SeqNo = item.SeqNo
                        });
                    }
                }
                return obj;
            }
            else
            {
                throw new Exception(objTemp.ErrorMessage);
            }
        }

        public List<CodeGenBL.ClassHeaderDto> GetClassByProjectId(int projectId)
        {
            CodeGenBL.CodeGenBLClient objCodeGen = new CodeGenBL.CodeGenBLClient();
            List<CodeGenBL.ClassHeaderDto> objResult = null;

            var objTemp = objCodeGen.GetClassByProjectId(new CodeGenBL.ProjectPKDto
            {
                ProjectId = projectId
            });

            if (objTemp.Status)
            {
                objResult = objTemp.Data;
            }
            else
            {
                throw new Exception(objTemp.ErrorMessage);
            }
            return objResult;
        }

        public int AddClass(ClassModelDto classDto)
        {
            int classId = 0;
            CodeGenBL.CodeGenBLClient objCodeGen = new CodeGenBL.CodeGenBLClient();

            var data = new CodeGenBL.ClassModelDto
            {
                Id = classDto.Id,
                Name = classDto.Name,
                ProjectId = classDto.ProjectId
            };
            data.Attributes = new List<CodeGenBL.AttributeModelDto>();
            if(classDto.GetAttributes()!=null)
            {
                foreach (var item in classDto.GetAttributes())
                {
                    data.Attributes.Add(new CodeGenBL.AttributeModelDto
                    {
                        AutoKey = item.Autokey,
                        DataType = item.DataType,
                        Display = item.Display,
                        DisplayLengthInGrid = item.DisplayLengthInGrid,
                        FieldDescription = item.FieldDescription,
                        FieldType = item.FieldType,
                        Id = item.Id,
                        Label = item.Label,
                        Length = item.Length,
                        Name = item.Name,
                        Nullable = item.Nullable,
                        Pk = item.Pk,
                        Search = item.Search,
                        SearchResult = item.SearchResult,
                        SeqNo = item.SeqNo
                    });
                }
            }
            var objTemp = objCodeGen.AddClass(data);
            if (objTemp.Status)
            {
                classId = objTemp.Data;
            }
            else
            {
                throw new Exception(objTemp.ErrorMessage);
            }
            return classId;
        }
    }
}
